home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / errmon.zip / ERRMON.ASM next >
Assembly Source File  |  1985-08-30  |  9KB  |  378 lines

  1.     name    ERRMON        ;version 1.1
  2.  
  3.     page    60,132
  4.  
  5.     comment *
  6.     monitors INT 13 disk i/o and reports any errors encountered;
  7.     version 1.1 also reports the offending command
  8.     and the drive, cylinder, head, sector and number of sectors requested
  9.  
  10.     AT disk change error is ignored
  11.     *
  12.  
  13.     .radix    16
  14.  
  15. attribute    equ    0f        ;video attribute for error message
  16. line        equ    24d        ;line for error message, 0-24
  17.  
  18. cr        equ    0dh
  19. lf        equ    0a
  20.  
  21. com_org    equ    100            ;ORG for com files
  22.  
  23. ;    error codes from IBM bios listings
  24. sense_fail    equ    0ff        ;not implemented on AT
  25. no_error    equ    0e0        ;not implemented on PC, XT
  26. write_fault    equ    0cc        ;not implemented on PC, XT
  27. undef_err    equ    0bbh
  28. not_rdy        equ    0aa        ;not implemented on PC, XT
  29. time_out    equ    80
  30. bad_seek    equ    40
  31. bad_cntlr    equ    20
  32. data_corrected    equ    11
  33. bad_eec        equ    10
  34. bad_track    equ    0bh        ;not implemented on AT
  35. bad_sector    equ    0a        ;not implemented on PC, XT
  36. dma_boundry    equ    9
  37. bad_dma        equ    8
  38. init_fail    equ    7
  39. media_change    equ    6        ;ignore this AT error
  40. bad_reset    equ    5
  41. record_not_fnd    equ    4
  42. write_protect    equ    3
  43. bad_addr_mark    equ    2
  44. bad_cmd        equ    1
  45.  
  46. popff    macro            ;simulate POPF to avoid any '286 problems
  47.     jmp    short $+3    ;jump around IRET
  48.     iret            ;pops IP, CS, FLAGS
  49.     push    cs        ;CS to stack
  50.     call    cs:$-2        ;IP to stack (cs: avoids masm error)
  51.     endm
  52.  
  53. entry    struc            ;map each entry in the error table
  54. err_nmbr    db    ?    ;error code number for this entry
  55. msg_offset    dw    ?    ;offset to message text for this error
  56. msg_len        db    ?    ;length of the message text
  57. entry    ends
  58.  
  59. stack    struc            ;stack structure
  60. cur_loc        dw    ?    ;save cursor location
  61. reg_bp        dw    ?
  62. reg_di        dw    ?
  63. reg_si        dw    ?
  64. reg_dx        dw    ?    ;cx and dx hold the
  65. reg_cx        dw    ?    ;    drive, cylinder, head, sector info
  66. reg_bx        dw    ?
  67. reg_ax        dw    ?
  68. reg_f        dw    ?    ;cy if error, code in ah
  69. stack    ends
  70.  
  71. errmon    segment    para    public    'CODE'
  72.     assume    cs:errmon
  73.     org    com_org
  74.  
  75. start:    jmp    init            ;go install
  76.  
  77. err_tbl    db    sense_fail
  78.     dw    msg_ff
  79.     db    len_ff
  80.     db    no_error
  81.     dw    msg_e0
  82.     db    len_e0
  83.     db    write_fault
  84.     dw    msg_cc
  85.     db    len_cc
  86. ude    db    undef_err
  87.     dw    msg_bb
  88.     db    len_bb
  89.     db    not_rdy
  90.     dw    msg_aa
  91.     db    len_aa
  92.     db    time_out
  93.     dw    msg_80
  94.     db    len_80
  95.     db    bad_seek
  96.     dw    msg_40
  97.     db    len_40
  98.     db    bad_cntlr
  99.     dw    msg_20
  100.     db    len_20
  101.     db    data_corrected
  102.     dw    msg_11
  103.     db    len_11
  104.     db    bad_eec
  105.     dw    msg_10
  106.     db    len_10
  107.     db    bad_track
  108.     dw    msg_0b
  109.     db    len_0b
  110.     db    bad_sector
  111.     dw    msg_0a
  112.     db    len_0a
  113.     db    dma_boundry
  114.     dw    msg_09
  115.     db    len_09
  116.     db    bad_dma
  117.     dw    msg_08
  118.     db    len_08
  119.     db    init_fail
  120.     dw    msg_07
  121.     db    len_07
  122. ;    db    media_change            ;ignore this AT error
  123. ;    dw    msg_06
  124. ;    db    len_06
  125.     db    bad_reset
  126.     dw    msg_05
  127.     db    len_05
  128.     db    record_not_fnd
  129.     dw    msg_04
  130.     db    len_04
  131.     db    write_protect
  132.     dw    msg_03
  133.     db    len_03
  134.     db    bad_addr_mark
  135.     dw    msg_02
  136.     db    len_02
  137.     db    bad_cmd
  138.     dw    msg_01
  139.     db    len_01
  140. nmbr_errs    equ    ($-err_tbl)/size entry
  141.  
  142. msg_ff    db    'Sense failure'
  143. len_ff    equ    $-msg_ff
  144. msg_e0    db    'Status error'
  145. len_e0    equ    $-msg_e0
  146. msg_cc    db    'Write fault'
  147. len_cc    equ    $-msg_cc
  148. msg_bb    db    'Undefined error'
  149. len_bb    equ    $-msg_bb
  150. msg_aa    db    'Drive not ready'
  151. len_aa    equ    $-msg_aa
  152. msg_80    db    'No response'
  153. len_80    equ    $-msg_80
  154. msg_40    db    'Seek failure'
  155. len_40    equ    $-msg_40
  156. msg_20    db    'Controller failure'
  157. len_20    equ    $-msg_20
  158. msg_11    db    'EEC error corrected'
  159. len_11    equ    $-msg_11
  160. msg_10    db    'Bad CRC/EEC on read'
  161. len_10    equ    $-msg_10
  162. msg_0b    db    'Bad track'
  163. len_0b    equ    $-msg_0b
  164. msg_0a    db    'Bad sector'
  165. len_0a    equ    $-msg_0a
  166. msg_09    db    'DMA boundry crossed'
  167. len_09    equ    $-msg_09
  168. msg_08    db    'DMA overrun'
  169. len_08    equ    $-msg_08
  170. msg_07    db    'Drive init failure'
  171. len_07    equ    $-msg_07
  172. ;msg_06    db    'Disk changed'            ;ignore this AT error
  173. ;len_06    equ    $-msg_06
  174. msg_05    db    'Drive reset failure'
  175. len_05    equ    $-msg_05
  176. msg_04    db    'Sector not found'
  177. len_04    equ    $-msg_04
  178. msg_03    db    'Disk write protected'
  179. len_03    equ    $-msg_03
  180. msg_02    db    'DAM not found'
  181. len_02    equ    $-msg_02
  182. msg_01    db    'Bad drive or command'
  183. len_01    equ    $-msg_01
  184.  
  185. msg_0    db    ' '            ;display location of error sector
  186. cmd    db    2 dup (0)
  187.     db    'D'
  188. drive    db    2 dup (0)
  189.     db    'C'
  190. cyl    db    4 dup (0)
  191.     db    'H'
  192. head    db    2 dup (0)
  193.     db    'S'
  194. sector    db    2 dup (0)
  195.     db    'N'
  196. number    db    2 dup (0)
  197. len_0    equ    $-msg_0
  198.  
  199. int13        label    dword
  200. sav_int13    dw    2 dup(0)    ;previous INT 13 vector
  201. sav_ax        dw    0        ;save command, number sectors requested
  202. sav_col        db    0        ;save number of screen columns
  203.  
  204. ;    INT 13 enters here
  205. error    proc    far
  206.     pushf                ;real INT 13 expects flags on stack
  207.     mov    cs:[sav_ax],ax        ;save command, number of sectors
  208.     call    cs:[int13]        ;do the real INT 13
  209.     jc    chk_6            ;go if we have an error condition
  210.     ret    2            ;else discard caller's flags and return
  211. chk_6:    pushf                ;save the flags from INT 13 for caller
  212.     cmp    ah,media_change        ;disk change error?
  213.     jne    valid_err        ;no
  214.     jmp    exit            ;yes, ignore it
  215.  
  216. ;    have a valid error, first save registers to be used
  217. valid_err:
  218.     push    ax    ;ah = error code
  219.     push    bx
  220.     push    cx    ;cl = sector and high bits of cylinder, ch = cylinder
  221.     push    dx    ;dl = drive, dh = head
  222.     push    si
  223.     push    di
  224.     push    bp
  225.  
  226. ;    find the error in the table
  227.     mov    di,offset err_tbl    ;=> table
  228.     mov    cx,nmbr_errs        ;load number of errors in table
  229. search:    cmp    ah,cs:[di].err_nmbr    ;no SCAS, can't override ES register!
  230.     je    found            ;got a match
  231.     add    di,size entry        ;bump to next table entry
  232.     loop    search
  233.     mov    di,offset ude        ;make it an undefined error
  234.  
  235. ;    find out where to print the report
  236. found:    mov    ah,15d
  237.     int    10            ;get current mode, columns, page
  238.     mov    cs:[sav_col],ah        ;save for end of line check
  239.     sub    ah,cs:[di].msg_len    ;columns less msg_x
  240.     sub    ah,len_0        ;less msg_0
  241.     jns    len_ok            ;if column >= 0
  242.     xor    ah,ah            ;else set column to 0
  243. len_ok:    mov    al,ah            ;starting column to al
  244.     mov    ah,line            ;row to ah
  245.     push    ax            ;save row, column to write to
  246.     mov    bp,sp            ;=> stack
  247.  
  248. ;    calculate the offending sector location
  249.     mov    si,offset drive
  250.     mov    ax,[bp].reg_dx
  251.     call    cvt1            ;process drive number
  252.     mov    si,offset head
  253.     mov    al,ah
  254.     call    cvt1            ;process head number
  255.     mov    si,offset cyl
  256.     mov    ax,[bp].reg_cx
  257.     mov    bl,al            ;save for later
  258.     and    al,11000000b        ;mask for high cyl bits    
  259.     rol    al,1
  260.     rol    al,1            ;move to low nibble
  261.     call    cvt1            ;process 1st part of cyl number
  262.     mov    al,ah
  263.     call    cvt1            ;process 2nd part of cyl number
  264.     mov    si,offset sector
  265.     mov    al,bl            ;restore
  266.     and    al,00111111b        ;mask for sector number bits
  267.     call    cvt1            ;process sector number
  268.     mov    si,offset number
  269.     mov    ax,cs:[sav_ax]
  270.     call    cvt1            ;process number of sectors
  271.     mov    si,offset cmd
  272.     mov    al,ah
  273.     call    cvt1            ;process command number
  274.  
  275. ;    write the report to the screen
  276.     mov    ah,3
  277.     int    10            ;get current cursor position
  278.     xchg    dx,[bp].cur_loc        ;swap cursor positions
  279.     mov    bl,attribute        ;video attribute
  280.     mov    cx,1            ;number characters to write
  281.     mov    si,cs:[di].msg_offset    ;=> msg_x
  282.     mov    di,cs:[di].word ptr msg_len    ;get len msg_x
  283.     and    di,0000000011111111b    ;need to clear high bits
  284.     call    write            ;write it
  285.     mov    si,offset msg_0        ;=> msg_0
  286.     mov    di,len_0        ;get len msg_0
  287.     call    write            ;write it
  288.     pop    dx            ;old cursor position
  289.     mov    ah,2
  290.     int    10            ;restore cursor position
  291.  
  292. ;    now let caller do its thing with the error
  293.     pop    bp
  294.     pop    di
  295.     pop    si
  296.     pop    dx
  297.     pop    cx
  298.     pop    bx
  299.     pop    ax
  300. exit:    popff
  301.     ret    2            ;done, discard flags from caller
  302. error    endp
  303.  
  304. ;    convert hex byte in al to two ascii digits, store in si, si+1
  305. cvt1    proc    near
  306.     mov    ch,al            ;will need again
  307.     mov    cl,4
  308.     shr    al,cl            ;high nibble to low
  309.     call    cvt2            ;make it ascii and store
  310.     mov    al,ch            ;recover byte
  311.     and    al,00001111b        ;mask for low nibble
  312. cvt2:    add    al,'0'            ;make an ascii digit
  313.     cmp    al,'9'            ;need adjustment?
  314.     jbe    no_adj            ;nope
  315.     add    al,7            ;adjust to A-F
  316. no_adj:    mov    cs:[si],al        ;stuff in msg_0
  317.     inc    si            ;bump pointer
  318.     ret
  319. cvt1    endp
  320.  
  321. ;    write a defined length string to the screen
  322. write    proc    near
  323.     cmp    cs:[sav_col],dl        ;end of line?
  324.     jbe    no_wrt            ;yes
  325.     mov    ah,2
  326.     int    10            ;reset cursor position
  327.     inc    dl            ;bump column
  328.     mov    al,cs:[si]        ;get char to write
  329.     inc    si            ;bump pointer
  330.     mov    ah,9
  331.     int    10            ;put it on screen
  332.     dec    di            ;decrement counter
  333.     jnz    write            ;if more to write
  334. no_wrt:    ret
  335. write    endp
  336.  
  337. pgm_len    equ    $-start+com_org        ;rinky dink to get an absolute constant
  338. remain    equ    pgm_len mod 10 gt 0    ;any remainder?
  339. prot    equ    (pgm_len/10)-remain    ;convert bytes to paragraphs, round